package surf.browser.component;


import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;

import surf.browser.Settings;
import surf.browser.TabManager;

/**
 * Stores a MozillaPane along with this tab's button.
 * @author Tom Cashman
 *
 */
public class TabPane extends JPanel implements Runnable, ActionListener {
	private static final long serialVersionUID = 1L;
	private int index;
	private JLabel m_label;
	private MozillaPane m_pane;
	private String url;
	private TabManager m_tabManager;
	
	/**
	 * Default constructor. Requires the tab manager to be passed as an argument.
	 * @param manager
	 */
	public TabPane(TabManager manager) {
		m_tabManager = manager;
		this.initialise();
		this.load(Settings.getHomepage());
	}
	
	/**
	 * Initialises the tabpane
	 */
	private void initialise() {
		//Set up the Tab Label
		m_label = new JLabel("Home");
		m_label.setSize(128, 24);
		m_label.setVisible(true);
		m_label.setLocation(0, 0);
		//m_label.setMinimumSize(new Dimension(96, 16));
		
		//Set up the browser itself
		m_pane = new MozillaPane();
		m_pane.setDoubleBuffered(true);
		this.setVisible(true);
		this.setSize(800, 600);
		this.setLocation(0, 24);
		this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
		
		this.add(m_pane);
	}
	
	/**
	 * Opens a new TabPane with a specific url
	 * @param manager
	 * @param url
	 */
	public TabPane(TabManager manager, String url) {
		m_tabManager = manager;
		this.initialise();
		this.load(url);
	}
	
	/**
	 * Closes this tab via the tab manager.
	 */
	public void close() {
		m_tabManager.close(this);
	}

	/**
	 * Loads a url. Called as a thread.
	 */
	public void run() {
		try {
			m_pane.load(url);
			setButtonText();
			m_tabManager.show(this);
		} catch (Exception e) {
			e.printStackTrace();
			m_tabManager.close(this);
		}
	}

	/**
	 * Opens this tab.
	 */
	public void actionPerformed(ActionEvent arg0) {
		this.setVisible(this.isVisible() ? false : true);
		this.setSize(this.getParent().getWidth(), this.getParent().getHeight() - 24);
		setButtonText();
		if(this.isVisible()) {
			m_tabManager.show(this);
		}
	}
	
	/**
	 * Sets this tab's button's text as the url loaded by the browser.
	 */
	public void setButtonText() {
		try {
			m_label.setText(m_pane.getChromeAdapter().getTitle().length() > 14 ?
						m_pane.getChromeAdapter().getTitle().substring(0, 15) :
							m_pane.getChromeAdapter().getTitle());
		} catch (Exception e) {
			m_label.setText(url.length() > 4 && url.substring(0, 4).equalsIgnoreCase("http") ?
	            		url.substring(6) : url);
		}
	}
	
	/**
	 * Sets this tab as visible/invisible
	 */
	public void setVisible(boolean b) {
		m_pane.getMozillaContainer().setVisible(b);
		m_pane.setVisible(b);
		super.setVisible(b);
	}
	
	/**
	 * Returns the tab button of this tab.
	 * @return
	 */
	public JLabel getLabel() {
		return m_label;
	}
	
	/**
	 * Loads a url.
	 * @param url
	 */
	public void load(String url) {
		this.url = url;
		new Thread(this).start();
	}
	
	/**
	 * Returns the actual browser of this tab.
	 * @return
	 */
	public MozillaPane getBrowser() {
		return m_pane;
	}
	
	/**
	 * Returns the tab manager.
	 * @return
	 */
	public TabManager getManager() {
		return m_tabManager;
	}
	
	/**
	 * Replaces default paint method allowing for error catching with the native interface.
	 */
	public void paint(Graphics g) {
		try {
			super.paint(g);
		} catch (Exception e) {
			m_tabManager.close(this);
		}
	}
	
	/**
	 * Replaces default updateUI method allowing for error catching with the native interface.
	 */
	public void updateUI() {
		try {
			super.updateUI();
		} catch (Exception e) {
			m_tabManager.close(this);
		}
	}

	/**
	 * Replaces default update method allowing for error catching with the native interface.
	 */
	public void update(Graphics g) {
		try {
			super.update(g);
		} catch (Exception e) {
			m_tabManager.close(this);
		}
	}
}
